////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef list_h__
#define list_h__

#include "core\types.h"

namespace Helper
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	List
	///
	/// \brief	This is a double linked list as you can also find it within the stl.
	///			Nothing special about it.
	///
	/// \author	khaos
	/// \date	11.12.2009
	////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T>
	class List
	{
		protected:

			class Node;

		public:

			class Iterator;




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	List()
			///
			/// \brief	Default constructor. 
			///
			/// \author	khaos
			/// \date	11.12.2009
			////////////////////////////////////////////////////////////////////////////////////////////////////
			List();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	List(const List<T> & rhs)
			///
			/// \brief	Constructor. 
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			List(const List<T> & rhs);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	~List()
			///
			/// \brief	Finaliser. 
			///
			/// \author	khaos
			/// \date	11.12.2009
			////////////////////////////////////////////////////////////////////////////////////////////////////
			~List();




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void operator= (const List<T> & rhs)
			///
			/// \brief	Copy operator. 
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void operator = (const List<T> & rhs);




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	tSize Size() const
			///
			/// \brief	Returns the size of the List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \return	The size of the List.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			tSize Size() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool IsEmpty() const
			///
			/// \brief	Determines if this List is empty.
			///
			/// \author	Khaos
			/// \date	02.01.2010
			///
			/// \return	True if this List is empty, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool IsEmpty() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Clear()
			///
			/// \brief	Clears this List and all of it's elements.
			///
			/// \author	khaos
			/// \date	11.12.2009
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Clear();




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void AddBefore(const T & element, Iterator itr)
			///
			/// \brief	Adds the specified element before the specified Iterator.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	element	The element we want to add to the list.
			/// \param	[in]	itr		The position where we want to add it.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddBefore(const T & element, Iterator itr);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void AddAfter(const T & element, Iterator itr)
			///
			/// \brief	Adds the specified element behind the specified Iterator.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	element	The element we want to add to the list.
			/// \param	[in]	itr		The position where we want to add it.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddAfter(const T & element, Iterator itr);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void AddList(const List<T> & rhs)
			///
			/// \brief	Adds a whole List to this List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	rhs	The List we want to add. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddList(const List<T> & rhs);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void AddFront(const T & element)
			///
			/// \brief	Adds the specified element to the front of the List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	element	The element we want to add.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddFront(const T & element);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void AddBack(const T & element)
			///
			/// \brief	Adds the specified element to the back of the List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	element	The element we want to add.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddBack(const T & element);




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void EraseFront()
			///
			/// \brief	Erases the first element of the List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			/////////////////////////////////////////////////////////////////////////////////////////////////////
			void EraseFront();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void EraseBack()
			///
			/// \brief	Erases the last element of the List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void EraseBack();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Erase(Iterator itr)
			///
			/// \brief	Erases the specified Node and returns its value.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	itr	The position of the Node we want to erase.
			///
			/// \return	The erased Node's value.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Erase(Iterator itr);




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	T & Front() const
			///
			/// \brief	Returns the first element of this List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \return	The first element of the List.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			T & Front() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	T & Back() const
			///
			/// \brief	Returns the last element of this List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \return	The last element of the List.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			T & Back() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Iterator Begin() const
			///
			/// \brief	Returns an Iterator pointing on the List's first element.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \return	An Iterator pointing to the List's first element.
			/////////////////////////////////////////////////////////////////////////////////////////////////////
			Iterator Begin() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Iterator End() const
			///
			/// \brief	Returns an Iterator pointing on the List's last element.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \return	An Iterator pointing to the List's last element.
			/////////////////////////////////////////////////////////////////////////////////////////////////////
			Iterator End() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Iterator Find(const T & element) const
			///
			/// \brief	If the specified element was found within the List an Iterator
			///			pointing towards it will be returned, if it wasn't found we will
			///			return NULL.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	element	The element we are looking for.
			///
			/// \return	An Iterator pointing towards the element we are looking for, otherwise NULL.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			Iterator Find(const T & element) const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Iterator Find(const T & element, Iterator start) const
			///
			/// \brief	This function is searching for the specified element an starts with
			///			this at the specified position. If the element was found within the
			///			List an Iterator pointing towards it will be returned, otherwise
			///			we will return NULL.
			///
			/// \author	khaos
			/// \date	11.12.2009
			///
			/// \param	[in]	element	The element we are looking for.
			/// \param	[in]	start	The start position for searching.
			///
			/// \return	If succeeded we got an Iterator pointing towards the element,
			///			otherwise NULL.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			Iterator Find(const T & element, Iterator start) const;




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \class	Iterator
			///
			/// \brief	This is just an Iterator within the List.
			///
			/// \author	khaos
			/// \date	11.12.2009
			/////////////////////////////////////////////////////////////////////////////////////////////////////
			class Iterator
			{
				public:

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Iterator()
					///
					/// \brief	Default constructor. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Iterator();




					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Iterator(Node * node)
					///
					/// \brief	Constructor. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	node	A node tat should be stored within this Iterator.
					/////////////////////////////////////////////////////////////////////////////////////////////////////
					Iterator(Node * node);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Iterator(const Iterator & rhs)
					///
					/// \brief	Copy constructor. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	rhs	Another Iterator.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Iterator(const Iterator & rhs);




					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	const Iterator & operator = (const Iterator & rhs)
					///
					/// \brief	Operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	rhs	The right hand side object. 
					///
					/// \return	Sets the Iterator and will return it also.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					const Iterator & operator = (const Iterator & rhs);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	bool operator== (const Iterator & rhs) const
					///
					/// \brief	Equality operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	rhs	The right hand side object. 
					///
					/// \return	True if both Iterators are equal, otherwise false.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					bool operator == (const Iterator & rhs) const;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	bool operator!= (const Iterator & rhs) const
					///
					/// \brief	Inequality operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	rhs	The right hand side object. 
					///
					/// \return	True if both Iterators are inequal, otherwise false.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					bool operator != (const Iterator & rhs) const;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	const Iterator & operator++ ()
					///
					/// \brief	Postfix increment operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	The incremented Iterator.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					const Iterator & operator ++ ();

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	const Iterator & operator-- ()
					///
					/// \brief	Postfix decrement operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	The decremented Iterator.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					const Iterator & operator -- ();

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Iterator operator++ (int)
					///
					/// \brief	Postfix increment operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	The. 
					///
					/// \return	The incremented Iterator.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Iterator operator ++ (int);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Iterator operator-- (int)
					///
					/// \brief	Postfix decrement operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	The. 
					///
					/// \return	The decremented Iterator.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Iterator operator -- (int);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	operator bool () const
					///
					/// \brief	Default constructor. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					////////////////////////////////////////////////////////////////////////////////////////////////////
					operator bool () const;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	T * operator-> () const
					///
					/// \brief	-> operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	Pointer to its element.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					T * operator -> () const;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	T & operator* () const
					///
					/// \brief	Reference operator. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	A reference to its element.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					T & operator * () const;

				protected:

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Node * GetNode() const
					///
					/// \brief	Returns a pointer to the Node.
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	Returns a pointer towards the Node.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Node * GetNode() const;

					Node * m_node;

				private:

			};

		protected:

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \class	Node
			///
			/// \brief	This is just a Node within the List holding an element and pointer to 
			///			their both neighbours.
			///
			/// \author	khaos
			/// \date	11.12.2009
			////////////////////////////////////////////////////////////////////////////////////////////////////
			class Node
			{
				public:

					friend class Iterator;
					friend class List;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Node(const T & element)
					///
					/// \brief	Constructor. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	element	The element this Node is containing.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Node(const T & element);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	~Node()
					///
					/// \brief	Destructor. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					////////////////////////////////////////////////////////////////////////////////////////////////////
					~Node();




					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	void SetNext(Node * next)
					///
					/// \brief	Sets the next element of this Node. 
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	next	Pointer to another Node.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					void SetNext(Node * next);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	void SetPrev(Node * prev)
					///
					/// \brief	Sets the previous element of this Node.
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \param	[in]	prev	Pointer to another Node.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					void SetPrev(Node * prev);

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Node * GetNext() const
					///
					/// \brief	Returns this Node's next Node.
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	Returns the next Node if available, otherwise NULL.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Node * GetNext() const;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	Node * GetPrev() const
					///
					/// \brief	Returns this Node's previous Node.
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	Returns the previous Node if available, otherwise NULL.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					Node * GetPrev() const;

					////////////////////////////////////////////////////////////////////////////////////////////////////
					/// \fn	T & Value()
					///
					/// \brief	Returns this Node's value.
					///
					/// \author	khaos
					/// \date	11.12.2009
					///
					/// \return	This Node's value.
					////////////////////////////////////////////////////////////////////////////////////////////////////
					T & Value();

				protected:

					Node * m_prev;
					Node * m_next;

					T m_value;

				private:

			};

			Node * m_head;
			Node * m_tail;

		private:

	};





	///
	template<class T>
	List<T>::Node::Node(const T &element):
	m_next(0),
		m_prev(0),
		m_value(element)
	{

	}


	///
	template<class T>
	List<T>::Node::~Node()
	{

	}




	///
	template<class T>
	void List<T>::Node::SetNext(typename List<T>::Node * next)
	{
		this->m_next = next;
	}


	///
	template<class T>
	void List<T>::Node::SetPrev(typename List<T>::Node *prev)
	{
		this->m_prev = prev;
	}


	///
	template<class T>
	typename List<T>::Node * List<T>::Node::GetNext() const
	{
		return this->m_next;
	}


	///
	template<class T>
	typename List<T>::Node * List<T>::Node::GetPrev() const
	{
		return this->m_prev;
	}


	///
	template<class T>
	T & List<T>::Node::Value()
	{
		return this->m_value;
	}





	///
	template<class T>
	typename List<T>::Node * List<T>::Iterator::GetNode() const
	{
		return this->m_node;
	}




	///
	template<class T>
	List<T>::Iterator::Iterator():
	m_node(NULL)
	{

	}


	///
	template<class T>
	List<T>::Iterator::Iterator(typename List<T>::Node *node):
	m_node(node)
	{

	}


	///
	template<class T>
	List<T>::Iterator::Iterator(const typename List<T>::Iterator &rhs):
	m_node(rhs.m_node)
	{

	}



	///
	template<class T>
	const typename List<T>::Iterator & List<T>::Iterator::operator =(const typename List<T>::Iterator &rhs)
	{
		if(this != &rhs)
			this->m_node = rhs.m_node;

		return *this;
	}


	///
	template<class T>
	bool List<T>::Iterator::operator ==(const typename List<T>::Iterator &rhs) const
	{
		return (this->m_node == rhs.m_node);
	}


	///
	template<class T>
	bool List<T>::Iterator::operator !=(const typename List<T>::Iterator &rhs) const
	{
		return (this->m_node != rhs.m_node);
	}


	///
	template<class T>
	const typename List<T>::Iterator & List<T>::Iterator::operator ++()
	{
		this->m_node = this->m_node->GetNext();

		return *this;
	}


	///
	template<class T>
	typename List<T>::Iterator List<T>::Iterator::operator ++(int)
	{
		Iterator result(this->m_node);

		this->m_node = this->m_node->GetNext();

		return result;
	}


	///
	template<class T>
	const typename List<T>::Iterator & List<T>::Iterator::operator --()
	{
		this->m_node = this->m_node->GetPrev();

		return *this;
	}


	///
	template<class T>
	typename List<T>::Iterator List<T>::Iterator::operator --(int)
	{
		Iterator result(this->m_node);

		this->m_node = this->m_node->GetPrev();

		return result;
	}


	///
	template<class T>
	List<T>::Iterator::operator bool() const 
	{
		return (this->m_node != 0);
	}


	///
	template<class T>
	T * List<T>::Iterator::operator ->() const 
	{
		return &(this->m_node->Value());
	}


	///
	template<class T>
	T &  List<T>::Iterator::operator *() const
	{
		return this->m_node->Value();
	}







	///
	template<class T>
	List<T>::List():
	m_head(0),
		m_tail(0)
	{

	}


	///
	template<class T>
	List<T>::List(const Helper::List<T> &rhs)
	{
		this->AddList(rhs);
	}


	///
	template<class T>
	List<T>::~List()
	{
		this->Clear();
	}




	///
	template<class T>
	void List<T>::operator =(const Helper::List<T> &rhs)
	{
		this->Clear();
		this->AddList(rhs);
	}




	///
	template<class T>
	bool List<T>::IsEmpty() const 
	{
		return (this->m_head == 0);
	}


	///
	template<class T>
	tSize List<T>::Size() const 
	{
		Iterator itr;
		tSize result;

		for(itr = this->m_head; itr != this->m_tail; itr++)
		{
			result++;
		}

		return result;
	}


	///
	template<class T>
	void List<T>::Clear() 
	{
		if(this->m_tail)
			this->EraseBack();
	}



	///
	template<class T>
	typename List<T>::Iterator List<T>::Begin() const 
	{
		return Iterator(this->m_head);
	}


	///
	template<class T>
	typename List<T>::Iterator List<T>::End() const
	{
		return Iterator(this->m_tail);
	}


	///
	template<class T>
	T & List<T>::Front() const
	{
		return this->m_head->Value();
	}


	///
	template<class T>
	T & List<T>::Back() const 
	{
		return this->m_tail->Value();
	}



	///
	template<class T>
	void List<T>::AddList(const Helper::List<T> &rhs)
	{
		Iterator itr;

		for(itr = rhs.Begin(); itr != rhs.End(); itr++)
		{
			this->AddBack(*itr);
		}
	}


	///
	template<class T>
	void List<T>::AddFront(const T &element)
	{
		Node * result =  r_new(Node(element));

		result.SetNext(this->m_head);

		result.SetPrev(NULL);

		this->m_front->SetPrev(result);

		this->m_head = result;
	}


	///
	template<class T>
	void List<T>::AddBack(const T &element)
	{
		Node * result = r_new(Node(element));

		result.SetPrev(this->m_tail);

		result.SetNext(NULL);

		this->m_prev->SetNext(result);

		this->m_tail = result;
	}


	///
	template<class T>
	void List<T>::AddAfter(const T &element, typename List<T>::Iterator itr)
	{
		Node * result = r_new(Node(element));

		result->SetNext(itr.GetNode()->GetNext());
		
		result->SetPrev(itr.GetNode());

		itr.GetNode()->SetNext(result);
	}


	///
	template<class T>
	void List<T>::AddBefore(const T &element, typename List<T>::Iterator itr)
	{
		Node * result = r_new(Node(element));

		result->SetPrev(itr.GetNode()->GetPrev());

		result->SetNext(itr.GetNode());

		itr.GetNode()->SetPrev(result);
	}




	///
	template<class T>
	void List<T>::Erase(typename List<T>::Iterator itr)
	{
		itr.GetNode()->GetPrev()->SetNext(itr.GetNode()->GetNext());

		itr.GetNode()->GetNext()->SetPrev(itr.GetNode()->GetPrev());

		r_delete(itr.GetNode());
	}


	///
	template<class T>
	void List<T>::EraseBack()
	{
		Node * temp = this->m_tail;

		this->m_tail = this->m_tail->GetPrev();

		r_delete(temp);
	}


	///
	template<class T>
	void List<T>::EraseFront()
	{
		Node * temp = this->m_head;

		this->m_head = this->m_head->GetNext();

		r_delete(temp);
	}



	///
	template<class T>
	typename List<T>::Iterator List<T>::Find(const T &element, Iterator start) const
	{
		if(start == NULL)
			Iterator temp(this->m_head);
		else
			Iterator temp = start;

		for(; temp != this->End(); temp++)
		{
			if(*start = element)
				return temp;
		}

		return NULL;
	}

	///
	template<class T>
	typename List<T>::Iterator List<T>::Find(const T &element) const
	{
		return this->Find(element, NULL);
	}

}

#endif // list_h__